/*
 * @Author: YURI
 * @Date: 2022-09-11 18:41:46
 * @LastEditTime: 2022-09-28 00:08:33
 * @Description: ecall 主程序
 */
#include "easycall.h"


typedef  struct{
    char *name;		     
    int  (*func)(char *);    
    char *doc;
}ecall_intner_cmd_t;

static int g_ecall_finish_flag=0;
ecall_ctl_t g_ecall_ctl;
int g_ecall_debug_enable = 0;
static int com_history(char *arg);
static int com_help(char *arg);
static int com_shell(char *arg);
static int com_quit(char *arg);
static int com_symbol(char *arg);
static int com_load_lib(char *arg);
static int com_list_lib(char *arg);
static int com_debug(char *arg);
static int com_get_value_byte(char *arg);
static int com_get_value_word(char *arg);
static int com_get_value_long(char *arg);
static int com_set_value_byte(char *arg);
static int com_set_value_word(char *arg);
static int com_set_value_long(char *arg);
static void ecall_show_help(void);
static ecall_ctl_t ecall_ctl_init(void);
static char *ecall_stripwhite(char *string);


ecall_intner_cmd_t commands[] = {
    { "h",       com_help,    "Display this help"},
    { "help",    com_help,    "Display this help"},
    { "?",       com_help,    "Display this help"},
    { "q",       com_quit,    "Quit using Ecall"},
    { "quit",    com_quit,    "Quit using Ecall"},
    { "debug",   com_debug,    "Set debug mode"},
    { "history", com_history, "List editline history"},
    { "list",    com_list_lib,    "List dynamic lib"},
    { "l",       com_load_lib,    "Load dynamic lib"},
    { "load",    com_load_lib,    "Load dynamic lib"},
    { "s",       com_symbol,      "Show dynamic lib's symbols"},
    { "symbol",  com_symbol,      "Show dynamic lib's symbols"},
    { "sh",     com_shell,      "Run shell cmd"},
    { "shell",  com_shell,      "Run shell cmd"},
    { "md.b",   com_get_value_byte,  "Get value as byte"},   
    { "md.w",   com_get_value_word,  "Get value as word"}, 
    { "md.l",   com_get_value_long,  "Get value as long"}, 
    { "nm.b",   com_set_value_byte,  "Get value as byte"},   
    { "nm.w",   com_set_value_word,  "Get value as word"}, 
    { "nm.l",   com_set_value_long,  "Get value as long"}, 
    { NULL, NULL, NULL },
};

static int com_set_value_byte(char *arg)
{
    int i,index = 0;
    uint8_t *val;
    uint8_t ori_val;
    char *p;
    int change_count=0;
    char name[EASY_CALL_MAX_LINE];
    int var[EASY_CALL_MAX_CHENG_NUMS];
    memset(name , 0, sizeof(name));
    memset(var , 0, sizeof(var));
    p = strtok(arg, " ");
    while(p != NULL){
        if(index == 0){
            strcpy(name , p);
        }else if(index == 1)
            change_count = strtoul(p,0,0);
        else{
            var[index-2] = strtoul(p,0,0);
        }
        p = strtok(NULL, " ");
        index++;
    }
    for(i = 0 ; i< g_easycall_lib_info_table.lib_index ; i++ )
    {
        val=(uint8_t*)easycall_find_symbols(g_easycall_lib_info_table.lib_table[i],name);
        if(val != NULL)break;
    }
    if(val==NULL)
    {
        val=(uint8_t*)strtoul(name,0,0);
    }
    
    for(i =0 ;i <change_count ;i++){
        ori_val=*val;
        *val= (uint8_t)var[i];
        ECALL_PRINT_LN("0x%lx\t:0x%x(%d) --> 0x%x(%d)",(uint64_t)val,(int)ori_val,(int)ori_val,(int)*val,(int)*val);
        val++;
    }
    return 0;
    
}
static int com_set_value_word(char *arg)
{
    int i,index = 0;
    uint16_t *val;
    uint16_t ori_val;
    char *p;
    int change_count=0;
    char name[EASY_CALL_MAX_LINE];
    int var[EASY_CALL_MAX_CHENG_NUMS];
    memset(name , 0, sizeof(name));
    memset(var , 0, sizeof(var));
    p = strtok(arg, " ");
    while(p != NULL){
        if(index == 0){
            strcpy(name , p);
        }else if(index == 1)
            change_count = strtoul(p,0,0);
        else{
            var[index-2] = strtoul(p,0,0);
        }
        p = strtok(NULL, " ");
        index++;
    }
    for(i = 0 ; i< g_easycall_lib_info_table.lib_index ; i++ )
    {
        val=(uint16_t*)easycall_find_symbols(g_easycall_lib_info_table.lib_table[i],name);
        if(val != NULL)break;
    }
    if(val==NULL)
    {
        val=(uint16_t*)strtoul(name,0,0);
    }
    
    for(i =0 ;i <change_count ;i++){
        ori_val=*val;
        *val= (uint16_t)var[i];
        ECALL_PRINT_LN("0x%lx\t:0x%x(%d) --> 0x%x(%d)",(uint64_t)val,(int)ori_val,(int)ori_val,(int)*val,(int)*val);
        val++;
    }
    return 0;
}
static int com_set_value_long(char *arg)
{
    int i,index = 0;
    uint32_t *val;
    uint32_t ori_val;
    char *p;
    int change_count=0;
    char name[EASY_CALL_MAX_LINE];
    int var[EASY_CALL_MAX_CHENG_NUMS];
    memset(name , 0, sizeof(name));
    memset(var , 0, sizeof(var));
    p = strtok(arg, " ");
    while(p != NULL){
        if(index == 0){
            strcpy(name , p);
        }else if(index == 1)
            change_count = strtoul(p,0,0);
        else{
            var[index-2] = strtoul(p,0,0);
        }
        p = strtok(NULL, " ");
        index++;
    }
    for(i = 0 ; i< g_easycall_lib_info_table.lib_index ; i++ )
    {
        val=(uint32_t*)easycall_find_symbols(g_easycall_lib_info_table.lib_table[i],name);
        if(val != NULL)break;
    }
    if(val==NULL)
    {
        val=(uint32_t*)strtoul(name,0,0);
    }
    
    for(i =0 ;i <change_count ;i++){
        ori_val=*val;
        *val= (uint32_t)var[i];
        ECALL_PRINT_LN("0x%lx\t:0x%x(%d) --> 0x%x(%d)",(uint64_t)val,(int)ori_val,(int)ori_val,(int)*val,(int)*val);
        val++;
    }
    return 0;
}
static int com_get_value_byte(char *arg)
{
    int i,index=0;
    uint8_t *val ;
    char *p;
    char name[EASY_CALL_MAX_LINE];
    int get_count=0;
    p = strtok(arg, " ");
    while(p != NULL){
        if(index == 0){
            strcpy(name , p);
        }else{
            get_count= strtoul(p,0,0);
            break;
        }
        p = strtok(NULL, " ");
        index++;
    }   
    for(i = 0 ; i< g_easycall_lib_info_table.lib_index ; i++ )
    {
        val=(uint8_t*)easycall_find_symbols(g_easycall_lib_info_table.lib_table[i],arg);
        if(val != NULL)break;
    }
    if(val==NULL)
    {
        val=(uint8_t*)strtoul(name,0,0);
    }
    for ( i =0 ; i< get_count ; i++){
        ECALL_PRINT_LN("0x%lx\t:0x%x(%d)",(uint64_t)val,(int)*val,(int)*val);
        val++;
    }
    return 0;
    
}
static int com_get_value_word(char *arg)
{
    int i,index=0;
    uint16_t *val ;
    char *p;
    char name[EASY_CALL_MAX_LINE];
    int get_count=0;
    p = strtok(arg, " ");
    while(p != NULL){
        if(index == 0){
            strcpy(name , p);
        }else{
            get_count= strtoul(p,0,0);
            break;
        }
        p = strtok(NULL, " ");
        index++;
    }   
    for(i = 0 ; i< g_easycall_lib_info_table.lib_index ; i++ )
    {
        val=(uint16_t*)easycall_find_symbols(g_easycall_lib_info_table.lib_table[i],arg);
        if(val != NULL)break;
    }
    if(val==NULL)
    {
        val=(uint16_t*)strtoul(name,0,0);
    }
    for ( i =0 ; i< get_count ; i++){
        ECALL_PRINT_LN("0x%lx\t:0x%x(%d)",(uint64_t)val,(int)*val,(int)*val);
        val++;
    }
    return 0;
}
static int com_get_value_long(char *arg)
{
    int i,index=0;
    uint32_t *val ;
    char *p;
    char name[EASY_CALL_MAX_LINE];
    int get_count=0;
    p = strtok(arg, " ");
    while(p != NULL){
        if(index == 0){
            strcpy(name , p);
        }else{
            get_count= strtoul(p,0,0);
            break;
        }
        p = strtok(NULL, " ");
        index++;
    }   
    for(i = 0 ; i< g_easycall_lib_info_table.lib_index ; i++ )
    {
        val=(uint32_t*)easycall_find_symbols(g_easycall_lib_info_table.lib_table[i],arg);
        if(val != NULL)break;
    }
    if(val==NULL)
    {
        val=(uint32_t*)strtoul(name,0,0);
    }
    for ( i =0 ; i< get_count ; i++){
        ECALL_PRINT_LN("0x%lx\t:0x%x(%d)",(uint64_t)val,(int)*val,(int)*val);
        val++;
    }
    return 0;
}
static int com_history(char *arg)
{
    const char *he;
    while (el_prev_hist()) ;
    for (he = el_next_hist(); he != NULL; he = el_next_hist())
	ECALL_PRINT_LN("%s\n", he);
    return 0;
}
static int com_debug(char *arg)
{
    g_ecall_debug_enable=!g_ecall_debug_enable;
    if(g_ecall_debug_enable){
        ECALL_PRINT_LN("debug on");
    }else{
        ECALL_PRINT_LN("debug off");
    }
    return 0;
}

static int com_shell(char *arg)
{
    int ret;
    char cmd[EASY_CALL_MAX_LINE];
    if(arg==NULL)arg=" ";
    strcpy(cmd,arg);
    ret=easycall_system(cmd);
    return ret;
}
int com_help(char *arg)
{
    int i;
    int printed = 0;
    for (i = 0; commands[i].name; i++) {
	if (!*arg || (strcmp(arg, commands[i].name) == 0)) {
	    ECALL_PRINT("%s\t\t%s.\n", commands[i].name,
		   commands[i].doc);
	    printed++;
	}
    }
    if (!printed) {
	ECALL_PRINT("No commands match `%s'.  Possibilties are:\n", arg);
	for (i = 0; commands[i].name; i++) {
	    if (printed == 6) {
		printed = 0;
		ECALL_PRINT("\n");
	    }
	    ECALL_PRINT("%s\t", commands[i].name);
	    printed++;
	}
	if (printed)
	    ECALL_PRINT("\n");
    }
    return 0;
}
static int com_quit(char *arg)
{
    g_ecall_finish_flag = 1;
    return 0;
}
static int com_symbol(char *arg)
{
    int index=0,i;
    
    index=atoi(arg);
    if(index<0)index=0;
    if(index>g_easycall_lib_info_table.lib_index)index=g_easycall_lib_info_table.lib_index;
    if(strlen(arg)==0){
        for(i=0 ; i < g_easycall_lib_info_table.lib_index ; i++)
        easycall_show_symbols(g_easycall_lib_info_table.lib_table[i].symbol_table);
    }else{
        easycall_show_symbols(g_easycall_lib_info_table.lib_table[index].symbol_table);
    }
    return 0;
}
static int com_load_lib(char *arg)
{
    easycall_load_library(arg);
    return 0;
}
static int com_list_lib(char *arg)
{
    int i=0;
    for(i = 0 ; i < g_easycall_lib_info_table.lib_index ; i++ )
    {
        ECALL_PRINT_LN("%d\t:%s" ,i,g_easycall_lib_info_table.lib_table[i].path);
    }
    return 0;
}
/**
 * @function: ecall_ctl_init
 * @description: ecall_ctl_t初始化
 * @return {*}
 * @author: yuri
 */
static ecall_ctl_t ecall_ctl_init(void)
{
    ecall_ctl_t ecall_ret;
    ecall_ret.server=NULL;
    ecall_ret.mode     = ECALL_RUN_LINE_MODE;
    ecall_ret.libtable = NULL;
    ecall_ret.lib_nums = 0;
    ecall_ret.fun_nums = 0;
    return ecall_ret;
}

/**
 * @function: ecall_stripwhite
 * @description: 去空格
 * @param {char} *string
 * @return {*}
 * @author: yuri
 */
static char *ecall_stripwhite(char *string)
{
    char *s, *t;
    for (s = string; isspace(*s); s++) ;
    if (*s == 0)
	return s;
    t = s + strlen(s) - 1;
    while (t > s && isspace(*t))
	t--;
    *++t = '\0';
    return s;
}

char * ecall_longest_common_prefix(char ** strs, int strsSize)
{
    int i,j;
    if(!strsSize)return "";
    int minLen = strlen(strs[0]);
    for(i = 1; i < strsSize; ++i)
    {
        if(minLen > strlen(strs[i]))
        {
        minLen = strlen(strs[i]);
        }
    }
    char* result = (char*)malloc(sizeof(char) * (minLen+1));
    result[0] = 0;
    for(i = 0; i < minLen; ++i)
    {
        for(j = 1; j < strsSize; ++j)
        {
            if(strs[j][i] != strs[0][i])
            return result;
        }
        result[i] = strs[0][i];
        result[i+1] = 0;
    }
    return result;
}
/**
 * @function: ecall_command_generator
 * @description: 自动补全回调
 * @param {char} *text
 * @param {int} state
 * @return {*}
 * @author: yuri
 */
char *ecall_command_generator(const char *text, int state)
{
    int i,j,k,s_len;
    const int match_max_nums=EASY_CALL_MAX_CMD_SHOW;
    static int list_index, len;
    easycall_symbol_info_t* symbol_info;
    int match;
    char* match_name[EASY_CALL_MAX_CMD_SHOW];
    char *name;
    if (!state) {
        list_index = 0;
        match=0;
        len = strlen(text);
        memset(match_name,0,list_index);
    }
    while ((name = commands[list_index].name)) {
	    list_index++;
        if (strncmp(name, text, len) == 0 && match <match_max_nums){
            match_name[match]=name;
            match++;
        }
    }
    for (i=0 ;i < g_easycall_lib_info_table.lib_index;i++)
    {
        for(j=0 ; j < 2 ; j++){
            if (j == 0){
                symbol_info= g_easycall_lib_info_table.lib_table[i].symbol_table.symtab;
                s_len= g_easycall_lib_info_table.lib_table[i].symbol_table.symtab_nums;
            }else{
                symbol_info= g_easycall_lib_info_table.lib_table[i].symbol_table.dynsym;
                s_len= g_easycall_lib_info_table.lib_table[i].symbol_table.dynsym_nums; 
            }
            for(k=0;k<s_len;k++){
                name=symbol_info[k].name;
                if (strncmp(name, text, len) == 0 && match <match_max_nums){
                    match_name[match]=name;
                    match++;
                }
            }
        }
    }
    if(match == 1){
        return strdup(match_name[0]);
    }else if(match == 0){
        return NULL;
    }else{
        return ecall_longest_common_prefix(match_name,match);
    }
    
}

/**
 * @function: 列出候选项
 * @description: 
 * @param {char} *token
 * @param {char} *
 * @return {*}
 * @author: yuri
 */
static int ecall_rl_list_possib(char *token, char ***av)
{
    int i,j,k,num=0, total = 0,s_len;
    char *name;
    char **copy;
    easycall_symbol_info_t* symbol_info;
    num= sizeof(commands)/sizeof(ecall_intner_cmd_t);

    for (i=0 ;i < g_easycall_lib_info_table.lib_index;i++)
    {
        for(j=0 ; j < 2 ; j++){
            if (j == 0){
                symbol_info= g_easycall_lib_info_table.lib_table[i].symbol_table.symtab;
                s_len= g_easycall_lib_info_table.lib_table[i].symbol_table.symtab_nums;
            }else{
                symbol_info= g_easycall_lib_info_table.lib_table[i].symbol_table.dynsym;
                s_len= g_easycall_lib_info_table.lib_table[i].symbol_table.dynsym_nums; 
            }
            num+=s_len;
        }
    }
    copy = malloc(num * sizeof(char *));

    for(i = 0 ;i<sizeof(commands)/sizeof(ecall_intner_cmd_t)-1;i++ )
    {
        name=commands[i].name;
        if (!strncmp(name, token, strlen (token))) {
            copy[total] = strdup(name);
            total++;
        }
    }

    for (i=0 ;i < g_easycall_lib_info_table.lib_index;i++)
    {
        for(j=0 ; j < 2 ; j++){
            if (j == 0){
                symbol_info= g_easycall_lib_info_table.lib_table[i].symbol_table.symtab;
                s_len= g_easycall_lib_info_table.lib_table[i].symbol_table.symtab_nums;
            }else{
                symbol_info= g_easycall_lib_info_table.lib_table[i].symbol_table.dynsym;
                s_len= g_easycall_lib_info_table.lib_table[i].symbol_table.dynsym_nums; 
            }
            for(k=0;k<s_len;k++){
                name=symbol_info[k].name;
                if (!strncmp(name, token, strlen (token))) {
                    copy[total] = strdup(name);
                    total++;
                }
            }
        }
    }
    *av = copy;
    return total;
}
char **ecall_completion(const char *text, int start, int end)
{
    char **matches = NULL;
    if (start == 0)
	matches = rl_completion_matches(text, ecall_command_generator);
    return matches;
}
void ecall_initialize_readline(void)
{
    rl_readline_name = "ecall";
    rl_attempted_completion_function = ecall_completion;
    rl_set_list_possib_func(&ecall_rl_list_possib);
}

ecall_intner_cmd_t *ecall_find_command(char *name)
{
    int i;
    for (i = 0; commands[i].name; i++)
	if (strcmp(name, commands[i].name) == 0)
	    return &commands[i];
    return NULL;
}

/**
 * @function: ecall_execute_line
 * @description: 执行命令
 * @param {char} *line
 * @return {*}
 * @author: yuri
 */
int ecall_execute_line(char *line)
{
    int i,ret;
    char* ori_cmd=(char*)malloc(strlen(line) * sizeof(char)+1) ;
    ecall_intner_cmd_t *command;
    easycall_func_info_t easycall_func_info;
    clock_t start_time,end_time;
    strcpy(ori_cmd,line);
    ori_cmd[strlen(line)]=0;
    char *word;
    i = 0;
    while (line[i] && isspace(line[i]))
	i++;
    word = line + i;
    while (line[i] && !isspace(line[i]))
	i++;
    if (line[i])
	line[i++] = '\0';
    command = ecall_find_command(word);
    if (!command) {
        easycall_func_info=easycall_analyse_func(ori_cmd);
        start_time=clock();
        ret=easycall_call_function(easycall_func_info);
        end_time=clock();
        easycall_func_info.run_time=(double)((double)end_time-start_time)/ CLOCKS_PER_SEC;
        if(ret==-1){
            ECALL_PRINT_LN("Unknown command!!!");
            return -1;
        }
        if(g_ecall_debug_enable){
            ECALL_PRINT_LN("THIS FUCTION USE CPU %lf s",easycall_func_info.run_time);
        }
        //find symbol
        return 0;
    }
    while (isspace(line[i]))
	i++;
    word = line + i;
    free(ori_cmd);
    return command->func(word);
}

/**
 * @function: ecall_show_help
 * @description: 显示帮助
 * @return {*}
 * @author: yuri
 */
static void ecall_show_help(void)
{
    ECALL_PRINT_LN("-l: [dynamic lib]");
    ECALL_PRINT_LN("\t link the library you want");

    ECALL_PRINT_LN("-e: [function name]");
    ECALL_PRINT_LN("\t run the function");

    ECALL_PRINT_LN("-h");
    ECALL_PRINT_LN("\t get my help");  

    ECALL_PRINT_LN("-f");
    ECALL_PRINT_LN("\t run a file as script");  

    ECALL_PRINT_LN("-d");
    ECALL_PRINT_LN("\t run as domain ");   
}

/**
 * @function: check_run_back
 * @description: 是否运行在后台
 * @param {char*} line
 * @return {*}
 * @author: yuri
 */
static int check_run_back(char* line)
{
    int back_index = strlen(line);
    while (back_index > 0 && !isspace(line[back_index]))
    {
        if(line[back_index] =='&')
        {
            line[back_index]='\0';
            return 1;
        }
        back_index--;
    }
    return 0;
}
/**
 * @function: ecall_execute_thread
 * @description: 线程执行
 * @param {char} *line
 * @return {*}
 * @author: yuri
 */
void* ecall_execute_thread(void* line)
{
    ecall_execute_line((char*)line);
    return (void*)line;
}

/**
 * @function: cmd_put_get_msg
 * @description: 
 * @param {uds_command_t} *req
 * @return {*}
 * @author: yuri
 */
uds_command_t *cmd_get_msg(uds_command_t *req)
{
    uds_command_t *res;
    uds_request_put_msg_t *put_msg = (uds_request_put_msg_t *)req;
    ecall_execute_line((char *)put_msg->data);
    res = (uds_command_t *)malloc(sizeof(uds_command_t));
    if (res != NULL) {
        res->status = STATUS_SUCCESS;
        res->data_len = 0;
    }
    return (uds_command_t *)res;
}
/**
 * @function: ecall_request_handler
 * @description: 服务器消息处理回调函数
 * @param {uds_command_t} *req
 * @return {*}
 * @author: yuri
 */
uds_command_t *ecall_request_handler(uds_command_t *req)
{
    uds_command_t *resp = NULL;
    switch (req->command) {
    case CMD_GET_MESSAGE:
        resp = cmd_get_msg(req);
        break;    
    default:
        break;
    }
    return resp;
}

int main(int argc ,char * argv[])
{
    FILE *fp;
    char file_line[EASY_CALL_MAX_LINE];
    char run_line[EASY_CALL_MAX_LINE];
    int ch,ret;
    pthread_t pid;
    int run_back=0;
    char *line, *s;
    char *p;
    char file_path[PATH_MAX];
    easycall_func_info_t easycall_func_info;
    
    g_ecall_ctl = ecall_ctl_init();
    easycall_show_license();
    while ((ch = getopt(argc , argv , "f:l:e:d::hd")) != -1)
    {
        switch (ch) 
        {
            case 'h':
                ecall_show_help();
                break;
            case 'l':
                easycall_load_library((char*)optarg);
                break;
            case 'e':
                //如果一旦使用了-e 就只运行一次
                g_ecall_ctl.mode = ECALL_RUN_ONCE_TIME_MODE;
                easycall_func_info=easycall_analyse_func((char*)optarg);
                ret=easycall_call_function(easycall_func_info);
                if(ret==-1){
                    ECALL_PRINT_LN("Unknown command!!!");
                    return -1;
                }
                break;
            case 'f':
                g_ecall_ctl.mode = ECALL_RUN_ONCE_TIME_MODE;
                memset(file_path,0,sizeof(file_path));
                if (realpath((char*)optarg, file_path)) {
                    file_path[PATH_MAX - 1] = 0;
                } else {
                    perror("realpath");
                    return -1;
                }
                fp=fopen(file_path,"r");
                if(fp == NULL) {
                    perror("file not exist");
                    return -1;
                }
                while(!feof(fp))
                {
                    memset(file_line,0,sizeof(file_line));
                    p = fgets(file_line,sizeof(file_line),fp);
                    if(p == NULL) 
                    {
                        perror("fgets error");
                    }
                    s = ecall_stripwhite(file_line);
                    if(strlen(s)>=1){
                        ECALL_PRINT_LN("%s",s);
                        ecall_execute_line(s);
                    }
                }
                break;
            case 'd':
                g_ecall_ctl.mode = ECALL_SERVER_MODE;
                break;
            default:
                ECALL_PRINT_LN("unknown args %c",ch);
                break;
         }
    }
    if(g_ecall_ctl.mode == ECALL_RUN_ONCE_TIME_MODE){//单次运行模式
        return 0;
    }
    else if(g_ecall_ctl.mode == ECALL_SERVER_MODE){//服务器模式
        if(fork()>0)exit(0);
        g_ecall_ctl.server = server_init( &ecall_request_handler);
        if (g_ecall_ctl.server == NULL) {
            printf("server: init error\n");
            return STATUS_INIT_ERROR;
        }
        while (g_ecall_finish_flag!=1) {
            server_accept_request(g_ecall_ctl.server);
        }
        server_close(g_ecall_ctl.server);
    }
    else{//命令行模式
        ecall_initialize_readline();
        while (g_ecall_finish_flag!=1)
        {
            line = readline("ecall$ ");
            if (!line)
                break;
            s = ecall_stripwhite(line);
            if (strlen(s) >0){
                run_back = check_run_back(s) ;
                strcpy(run_line,s);
                if(run_back == 1){//后台运行
                    ret=pthread_create(&pid,NULL,ecall_execute_thread,(void*)run_line);
                    if(ret<0)
                    {
                        perror("pthread_create");
                        return -1;
                    }                
                }else{//直接运行        
                    ecall_execute_line(s);
                }
            }
            free(line);
        }
    }
    return 0;
}

